<?php
/**
 * MAF
 **
 * File:
**/

/**
 * Class: MAF: Autoload
 **
 * @package MAF
 * @subpackage Core
**/
class maf__autoload
	implements maf__i__singletone {

	/**
	 * Handlers list:
	 * array(
	 * 	key => callback
	 * )
	 **
	 * @param array
	**/
	static protected $handlers = array();

	/**
	 * Classes list:
	 * array(
	 * 	class => file
	 * )
	**/
	static protected $classes   = array();
	static protected $functions = array();

	/**
	 * @return maf__autoload
	**/
	static public function getInstance() {

		static $instance;

		if( !isset($instance) ) {
			$instance = new self; }

		return $instance;

	}	# Function

	private function __clone() {
	}	# Function

	private function __construct() {
	}	# Function

	static public function getRegisteredFunctions() {

		return self::$functions;

	}	# Function

	static public function getRegisteredClasses() {

		return self::$classes;

	}	# Function

	/**
	 * @param string $_class_
	 * @param string $_file_
	**/
	static public function registerFunction($_function_, $_file_, $_autocomplete_ = FALSE) {

		if( $_autocomplete_ ) {
			$_file_ = "{$_file_}/function.{$_function_}.php"; }

		if( !is_file($_file_) ) {
			trigger_error("Unable to register function '$_function_' to unexistent file '$_file_'"); }

		self::$functions[ strtolower((string) $_function_) ] = (string) $_file_;

	}	# Function

	/**
	 * @param string $_function_
	**/
	static public function unregisterFunction($_function_) {

		unset( self::$functions[ strtolower((string) $_function_) ] );

	}	# Function

	/**
	 * @param ~string $_class_
	 * @param ~string $_file_
	**/
	static public function registerClass($_class_, $_file_, $_autocomplete_ = FALSE) {

		if( $_autocomplete_ ) {
			$_file_ = "{$_file_}/class.{$_class_}.php"; }

		if( !is_file($_file_) ) {
			trigger_error("Unable to register class '$_class_' to unexistent file '$_file_'"); }

		self::$classes[ strtolower((string) $_class_) ] = (string) $_file_;

	}	# Function

	/**
	 * @param string $_class_
	**/
	static public function unregisterClass($_class_) {

		unset( self::$classes[ strtolower((string) $_class_) ] );

	}	# Function

	/**
	 * @param ~string $_class_
	 * @param ~string $_file_
	**/
	static public function registerInterface($_class_, $_file_, $_autocomplete_ = FALSE) {

		if( $_autocomplete_ ) {
			$_file_ = "{$_file_}/interface.{$_class_}.php"; }

		if( !is_file($_file_) ) {
			trigger_error("Unable to register interface '$_class_' to unexistent file '$_file_'"); }

		self::$classes[ strtolower((string) $_class_) ] = (string) $_file_;

	}	# Function

	/**
	 * @param string $_class_
	**/
	static public function unregisterInterface($_class_) {

		unset( self::$classes[ strtolower((string) $_class_) ] );

	}	# Function

	/**
	 * @param ~string $_class_
	 * @param ~string $_file_
	**/
	static public function registerException($_class_, $_file_, $_autocomplete_ = FALSE) {

		if( $_autocomplete_ ) {
			$_file_ = "{$_file_}/exception.{$_class_}.php"; }

		if( !is_file($_file_) ) {
			trigger_error("Unable to register exception class '$_class_' to unexistent file '$_file_'"); }

		self::$classes[ strtolower((string) $_class_) ] = (string) $_file_;

	}	# Function

	/**
	 * @param string $_class_
	**/
	static public function unregisterException($_class_) {

		unset( self::$classes[ strtolower((string) $_class_) ] );

	}	# Function

	/**
	 * @param  callback $_callback_
	 **
	 * @return integer
	**/
	static public function registerHandler($_callback_) {

		self::$handlers[] = $_callback_;
		return key(self::$handlers);

	}	# Function

	/**
	 * @param integer $_key_
	**/
	static public function unregisterHandler($_key_) {

		unset(self::$handlers[$_key_]);

	}	# Function

	/**
	 * @return array
	**/
	static public function getHandlers() {

		return self::$handlers;

	}	# Function

	/**
	 * @param string $_function_
	 **
	 * @return boolean
	**/
	static public function importFunction($_function_) {

		$_function_ = strtolower((string) $_function_);

		if( function_exists($_function_) ) {
			true; }

		if( isset( self::$functions[$_function_] ) ) {

			require_once( self::$functions[$_function_] );
			return function_exists($_function_);

		}	# if

		return FALSE;

	}	# Function

	/**
	 * @param  string $_class_
	 **
	 * @return boolean
	**/
	static public function importClass($_class_) {

		$_class_ = (string) $_class_;

		if( class_exists($_class_, FALSE) || interface_exists($_class_, FALSE) ) {
			true; }

		if( isset( self::$classes[ strtolower($_class_) ] ) ) {

			require_once( self::$classes[ strtolower($_class_) ] );

			if( class_exists($_class_, FALSE) || interface_exists($_class_, FALSE) ) {
				return TRUE; }

		}	# if

		foreach( array_reverse(self::$handlers) as $_handler ) {

			call_user_func($_handler, $_class_);

			if( class_exists($_class_, FALSE) || interface_exists($_class_, FALSE) ) {
				return TRUE; }

		}	# foreach

		return FALSE;

	}	# Function

}	# Class

/* EOF */